package com.qiyue.admin.biz.base;

import com.ace.cache.annotation.CacheClear;
import com.qiyue.admin.constant.AdminCommonConstant;
import com.qiyue.admin.constant.RedisConstant;
import com.qiyue.admin.entity.base.Element;
import com.qiyue.admin.entity.base.Menu;
import com.qiyue.admin.entity.base.ResourceAuthority;
import com.qiyue.admin.entity.base.group.Group;
import com.qiyue.admin.entity.base.group.GroupLeader;
import com.qiyue.admin.entity.base.group.GroupMember;
import com.qiyue.admin.repository.base.MenuRepsoitory;
import com.qiyue.admin.repository.base.ResourceAuthorityRepsitory;
import com.qiyue.admin.repository.base.group.GroupLeaderRepsitory;
import com.qiyue.admin.repository.base.group.GroupMemberRepsitory;
import com.qiyue.admin.repository.base.group.GroupRepsitory;
import com.qiyue.admin.vo.AuthorityMenuTree;
import com.qiyue.admin.vo.GroupUsers;
import com.qiyue.common.biz.BaseBiz;
import io.swagger.annotations.ApiModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by y747718944 on 2018/2/7
 */
@Service
@Transactional(rollbackOn = Exception.class)
@SuppressWarnings("all")
public class GroupBiz extends BaseBiz<GroupRepsitory,Group,Long> {

    private  final static Logger logger= LoggerFactory.getLogger(GroupBiz.class);

    @Autowired
    private  UserBiz userBiz;

    @Autowired
    private GroupLeaderRepsitory groupLeaderRepsitory;//群组领导dao
    @Autowired
    private GroupMemberRepsitory groupMemberRepsitory;//群员dao
    @Autowired
    private ResourceAuthorityRepsitory resourceAuthorityRepsitory;//资源管理dao

    @Autowired
    private MenuBiz menuBiz;
    @Autowired
    private ElementBiz elementBiz;

    //重写保存方式
    public Group save(Group entity){
        //判断是否是root 来判断path
        if (AdminCommonConstant.ROOT == entity.getParentId()) {
            entity.setPath("/" + entity.getCode());
        } else {
            Group parent =this.findOne(entity.getParentId());
            entity.setPath(parent.getPath() + "/" + entity.getCode());
        }
        return  super.save(entity);
    }


    /**
     * 获取群组关联用户
     * @param groupId
     * @return
     */
    public GroupUsers getGroupUsers(Long groupId){

        return new GroupUsers(userBiz.queryMemberByGroupId(groupId),userBiz.queryLeaderByGroupId(groupId));
    }


    /**
     *  变更群组所分配的用户
     * @param groupId
     * @param members
     * @param leaders
     */
    @CacheClear(key= RedisConstant.PERMISSION)
    public void modifyGroupUsers(Long groupId,String members,String leaders){
        //清空群组内容
        groupLeaderRepsitory.deleteByGroupId(groupId);
        groupMemberRepsitory.deleteByGroupId(groupId);
        //从新进行分配
        if (!StringUtils.isEmpty(members)) {
            String[] mem = members.split(",");
            for (String m : mem) {
                groupMemberRepsitory.save(new GroupMember(groupId,  userBiz.findOne(Long.parseLong(m))));
            }
        }

        if (!StringUtils.isEmpty(leaders)) {
            String[] leas = leaders.split(",");
            for (String l : leas) {

                groupLeaderRepsitory.save(new GroupLeader(groupId,  userBiz.findOne(Long.parseLong(l))));
            }
        }
    }


    /**
     * 变更群组关联的菜单
     * @param groupId
     * @param menus
     */
    @CacheClear(pre = RedisConstant.PERMISSION_MENU)
    public void modifyAuthorityMenu(Long groupId,String[] menus){
        //删除对应的 group 的菜单类型
        resourceAuthorityRepsitory.deleteByAuthorityIdAndResourceType(groupId,AdminCommonConstant.RESOURCE_TYPE_MENU);
        //获取全部菜单项
       List<Menu> menuList=menuBiz.findAll();

        Map<String, String> map = new HashMap<String, String>();//全部菜单项
        for (Menu menu : menuList) {
            map.put(menu.getId().toString(), menu.getParentId().toString());
        }
        Set<String> relationMenus = new HashSet<String>();
        relationMenus.addAll(Arrays.asList(menus));//将菜单数组转化为list

        for (String menuId : menus) {
            findParentID(map, relationMenus, menuId);
        }
        //将新的

        List<ResourceAuthority> entityList=new ArrayList<ResourceAuthority>();
        ResourceAuthority authority = null;
        logger.info("新分组的菜单表:{}",relationMenus);
        for (String menuId : relationMenus) {
            Long id=Long.parseLong(menuId);
            if ( id == AdminCommonConstant.RESOURCE_DEFAULT_ROOT_MENU)  continue;
            authority = new ResourceAuthority(AdminCommonConstant.AUTHORITY_TYPE_GROUP, AdminCommonConstant.RESOURCE_TYPE_MENU);
            authority.setAuthorityId(groupId);
            //新增权限关联关系
            authority.setMenu(menuBiz.findOne(id));
            authority.setParentId(AdminCommonConstant.RESOURCE_DEFAULT_ROOT_MENU);
            entityList.add(authority);
        }
        //批量添加list
        resourceAuthorityRepsitory.save(entityList);

    }

    /**
     *  递归查询菜单的父id并加入数组中
     * @param map
     * @param relationMenus
     * @param id
     */
    private void findParentID(Map<String, String> map, Set<String> relationMenus, String id) {
        String parentId = map.get(id);
        if (String.valueOf(AdminCommonConstant.ROOT).equals(id)) {
            return;
        }
        relationMenus.add(parentId);
        findParentID(map, relationMenus, parentId);
    }

    /**
     *  新增资源权限
     * @param groupId
     * @param menuId
     * @param elementId
     */
    @CacheClear(pre = "permission:ele")
    public void modifyAuthorityElement(Long groupId,Long menuId,Long elementId){
        ResourceAuthority authority = new ResourceAuthority(AdminCommonConstant.AUTHORITY_TYPE_GROUP, AdminCommonConstant.RESOURCE_TYPE_BTN);
        authority.setAuthorityId(groupId);
        authority.setMenu(menuBiz.findOne(menuId));
        authority.setElement(elementBiz.findOne(elementId));
        authority.setParentId(AdminCommonConstant.RESOURCE_DEFAULT_ROOT_BUTTON);
        resourceAuthorityRepsitory.save(authority);
    }


    /**
     * 移除资源权限
     *
     * @param groupId
     * @param menuId
     * @param elementId
     */
    @CacheClear(pre = "permission:ele")
    public void removeAuthorityElement(Long groupId, Long menuId, Long elementId) {
        ResourceAuthority authority = new ResourceAuthority();
        authority.setAuthorityId(groupId);
        authority.setMenu(menuBiz.findOne(menuId));
        authority.setElement(elementBiz.findOne(elementId));
        authority.setParentId(AdminCommonConstant.RESOURCE_DEFAULT_ROOT_MENU);
        resourceAuthorityRepsitory.delete(authority);
    }



    /**
     * 获取群组关联的菜单
     * @param groupId
     * @return
     */
    public List<AuthorityMenuTree> getAuthorityMenu(Long groupId) {
        //获取分组对应的菜单内容
        List<Menu> menus =menuBiz.selectMenuByAuthorityId(groupId,AdminCommonConstant.AUTHORITY_TYPE_GROUP);
        //进行树结构调整
        List<AuthorityMenuTree> trees = new ArrayList<AuthorityMenuTree>();
        AuthorityMenuTree node = null;
        for (Menu menu : menus) {
            node = new AuthorityMenuTree();
            node.setText(menu.getTitle());
            BeanUtils.copyProperties(menu, node);
            trees.add(node);
        }
        logger.info("群组:{} 菜单树结构:{}",groupId,trees);
        return trees;
    }

    /**
     * 获取群组关联的资源
     * @param groupId
     * @return
     */
    public List<Long> getAuthorityElement(Long groupId) {
        List<ResourceAuthority> authorities =resourceAuthorityRepsitory.findByAuthorityTypeAndResourceTypeAndAuthorityId(AdminCommonConstant.AUTHORITY_TYPE_GROUP, AdminCommonConstant.RESOURCE_TYPE_BTN,groupId);

        List<Long> ids = authorities
                .stream()
                .map( resourceAuthority -> resourceAuthority.getElement().getId())
                .collect(Collectors.toList());
        logger.info("群组:{} 资源结构:{}",groupId,ids);

        return ids;
    }

}
